首先,我們得先理解 JavaScript 的作用域為何?
JavaScript 的屬於靜態作用域,意思是當變數在解析後就會確定作用域,並且不會隨著 function 的執行而改變作用域。
以下簡單範例:
var value = 'JK';
function fun1(){
console.log(value);
}
function fun2(){
var value = 'JS';
fun1();
}
fun2(); // JK
因為變數解析後已經確定了作用域,所以 fun2()
裡面的 value 只會存在於 fun2()
裡面,當 fun2()
執行 fun1()
的時候,fun1()
console value 這個變數,該變數會找到的是在外面的 value 變數。
而剛剛提到的"找到的是在外面的 value 變數"這句話,意指在作用域中找不到變數,所以跑去外層找的這個動作(特性)。又被稱為範圍鍊(scope chain)。
有時會看到翻譯為執行脈絡或執行上下文都是指一樣的東西喔。
JavaScript 的執行環境又分為創建與執行兩個階段。在創建階段的時候,記憶體裡面會有全域變數(Global Object)、this 以及外部環境(Outer Environment)。變數與 function 被宣告時也包含在創建階段,所以才會有以下範例發生。
var a = 1;
這行程式碼具體上是先宣告 a,接著才賦予1
var a; // 創建
a = 1; // 執行
雖然看起來不起眼不過卻是個重要的特性,因為變數在宣告後會發生 Hoisting(提升) 這個特性。
Hoisting 會將目前宣告的變數移動到程式的最上面。
任何變數在未賦予值之前都是 undefined
。
以下簡單範例
console.log(b); // a is not defined
console.log(a); // undefined
var a = '鯊魚';
該段程式碼具體解析過程看起來為
var a;
console.log(b); // a is not defined
console.log(a); // undefined
a = '鯊魚';
所以 a 才會是 undefined
而不是 not defined
。
大概是這樣子,其實今天意外蠻短的,我以為會寫很多@@
明天我會介紹 Hoisting,多多關注盡請期待喔~~附註: a 為甚麼會等於鯊魚?因為鯊魚的叫聲就是 a。